﻿namespace ChinaUnicom.Schedule
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    internal class ScheduleStack : IDisposable, IEnumerable<ITask>
    {
        Dictionary<int, ITask> stack;
        int topKey = 0;

        public ScheduleStack()
        {
            stack = new Dictionary<int, ITask>();
        }

        public ITask Peek()
        {
            lock (stack)
            {
                if (Count == 0)
                {
                    throw new Exception("No items in ScheduleStack.");
                }

                return stack[topKey];
            }
        }

        public ITask Pop()
        {
            lock (stack)
            {
                if (Count == 0)
                {
                    throw new Exception("No items in ScheduleStack.");
                }

                ITask item = stack[topKey];
                stack.Remove(topKey);

                if (Count > 0)
                {
                    topKey = stack.Keys.Max();
                }
                else
                {
                    topKey = 0;
                }

                return item;
            }
        }

        public void Push(ITask task)
        {
            lock (stack)
            {
                var item = stack.SingleOrDefault(x => x.Value == task);

                if (item.Value != null)
                {
                    stack.Remove(item.Key);
                }

                stack.Add(++topKey, task);
            }
        }

        public int Count { get { return stack.Count; } }

        public void Dispose()
        {
            stack.Clear();
        }

        #region IEnumerable<ITask> members

        public IEnumerator<ITask> GetEnumerator()
        {
            if (Count == 0)
            {
                return new List<ITask>().GetEnumerator();
            }

            return stack.Select(x => x.Value).GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
